<script setup lang="ts">
import { tableConfig } from './config/table-config';
import { doAddProcedureList } from '@/api/procedure/index';
import { checkRepeat, isArray, RepeatMsg } from '@/utils/common';
import baseTable from '@/components/base-ui/base-table/index.vue';
import equipment from '@/views/Modeling/ProcessManagement/view/ProcedureList/dialog/equipment/index.vue';
import auxiliary from '@/views/Modeling/ProcessManagement/view/ProcedureList/dialog/auxiliary/index.vue';
import { generateId, transformValue } from '@/utils';
import useEmit from '@/hooks/useEmitter';
import { message } from '@/components/q-message/message';
import usePageSave from '@/hooks/usePageSave';
import type { EquipmentData } from '@/api/modeling/equipment/model/type';
import type { AuxiliaryData } from '@/api/modeling/auxiliaryResources/model/type';
import type {
    ProcedureData,
    WorkingProcedureEquipments,
    WorkingProcedureAuxiliary
} from '@/api/procedure/model/type';
import { cloneDeep } from 'lodash-es';

defineOptions({
    name: 'ProcedureListAdd'
});

const STORE_KEY = 'procedureAddData';

const { startRecording, isUpdate } = useEmit(STORE_KEY); // 页面标签路由关闭二次确认事件监听 EventBus

const { modalOk, modalSlotRef, loading } = useModal();

useRecordData(modalSlotRef, STORE_KEY, isUpdate, startRecording); // 复制工序相关

/**
 * @: 新增数据
 */
const handleSubmit = async () => {
    const tableData = modalSlotRef.value?.getSaveData();
    const saveData = cloneDeep(tableData);
    const msg = checkRepeat(saveData, ['processCode']); // 检查是否工序编码存在重复
    if (msg) {
        const { line, value } = msg;
        RepeatMsg({ line, value, label: '工序编码' }); // 给与重复工序编码提示
        return;
    }

    // 处理提交表格数据，删除不必要字段，保留后端接口需要的相关字段
    const params = saveData.map((data: ProcedureData) => {
        data.workingProcedureEquipments.map(equipmentItem => {
            delete equipmentItem.markId;

            equipmentItem.workingProcedureAuxiliary =
                equipmentItem.workingProcedureAuxiliary.filter(auxiliaryItem => {
                    delete auxiliaryItem.pMarkId;
                    delete auxiliaryItem.markId;

                    return auxiliaryItem.auxiliaryId;
                });
        });
        return data;
    });

    try {
        const res = await doAddProcedureList(params);
        if (res) {
            message.success('新增工序成功！');
        }
        return res;
    } catch (error) {
        console.log(error);
    }
};

/**
 * @: 设备编码相关逻辑
 */
const equipmentRef = ref<InstanceType<typeof equipment>>();
let currentRowData: ProcedureData;
let currentMarkId: string | null = null; // 记录当前选择设备的标记id, 用于选择设备后匹配对应工序下所处设备，并回显使用
const openEquipment = (row: ProcedureData, item: WorkingProcedureEquipments) => {
    currentRowData = row;
    currentMarkId = item.markId as string;
    equipmentRef.value?.open(item.equipmentId!);
};

/**
 * @: 设备编码弹框点击确定
 */
const equipmentSubmit = (row: EquipmentData) => {
    if (isArray(row)) return;
    const workingProcedureEquipment = currentRowData.workingProcedureEquipments.filter(
        item => item.markId === currentMarkId
    )[0];

    if (workingProcedureEquipment) {
        workingProcedureEquipment.equipmentId = row.id!; // 设备id
        workingProcedureEquipment.equipmentNumber = row.equipmentNumber; // 设备编码
        workingProcedureEquipment.deviceName = row.deviceName; // 设备名称
    }
};

/**
 * @: 辅助资源相关逻辑
 */
const auxiliaryRef = ref<InstanceType<typeof auxiliary>>();
let currentPMarkId: string | null = null;
const openAuxiliary = (row: any, item: WorkingProcedureAuxiliary) => {
    currentRowData = row;
    currentPMarkId = item.pMarkId as string; // 记录当前辅助资源父标记 markId, 用于选择辅助资源后，匹配对应当前工序中所处哪一个设备中。
    currentMarkId = item.markId as string; // 记录当前辅助资源标记 markId, 用于选择辅助资源后，匹配当前工序所处设备中哪一个辅助资源，并匹配对应辅助资源进行数据更新操作。
    auxiliaryRef.value?.open(item.auxiliaryId!);
};

/**
 * @: 辅助资源弹框点击确定
 */
const auxiliarySubmit = (row: AuxiliaryData) => {
    if (isArray(row)) return;
    // 根据记录父标记markId, 匹配得到对应设备数据
    const workingProcedureEquipment = currentRowData.workingProcedureEquipments.filter(
        item => item.markId === currentPMarkId
    )[0];

    if (workingProcedureEquipment) {
        // 根据记录标记markId, 匹配得到当前对应设备的辅助资源
        const workingProcedureAuxiliary =
            workingProcedureEquipment.workingProcedureAuxiliary.filter(
                item => item.markId === currentMarkId
            )[0];
        if (workingProcedureAuxiliary) {
            workingProcedureAuxiliary.auxiliaryId = row.id; // 辅助资源id
            workingProcedureAuxiliary.auxiliaryDataCoding = row.auxiliaryResourceCoding; // 辅助资源编码
            workingProcedureAuxiliary.auxiliaryResourceName = row.auxiliaryResourceName; // 辅助资源名称
        }
    }
};

/**
 * 点击保存按钮
 */
const handleOk = async () => {
    try {
        await modalOk(handleSubmit);
        usePageSave('/process/procedureList');
    } catch (e) {
        console.log(e);
    }
};

// 监听表格数据变化，初始化设备编码与辅助资源选项
const initAuxiliary: WorkingProcedureAuxiliary = {
    auxiliaryId: null,
    auxiliaryResourceName: null,
    auxiliaryDataCoding: null
};
const initEquipmentData: WorkingProcedureEquipments = {
    equipmentId: null,
    equipmentNumber: null,
    deviceName: null,
    workingProcedureAuxiliary: [initAuxiliary]
};

const handleAdd = (data: ProcedureData[]) => {
    if (data == null) return;
    const markId = generateId(); // 生成标记 id
    const equipmentData = cloneDeep(initEquipmentData);
    data.map((item: ProcedureData) => {
        if (!item.workingProcedureEquipments) {
            equipmentData.markId = markId;
            equipmentData.workingProcedureAuxiliary.map(item => {
                item.markId = item.pMarkId = markId;
            });
            item.workingProcedureEquipments = [equipmentData];
        }
    });
};

/**
 * 重新初始化生成设备编码数据
 */
const regenEquipMent = () => {
    const markId = generateId(); // 生成标记 id
    const equipmentData = cloneDeep(initEquipmentData);
    equipmentData.markId = markId;
    equipmentData.workingProcedureAuxiliary.map(item => {
        item.markId = item.pMarkId = markId;
    });
    return equipmentData;
};

/**
 * 当前工序下新增对应设备编码
 */
const addEquipment = (row: ProcedureData, id: string) => {
    const rowIndex = row.workingProcedureEquipments.findIndex(item => item.markId === id);
    const equipmentData = regenEquipMent();
    row.workingProcedureEquipments.splice(rowIndex + 1, 0, equipmentData);
};

/**
 * 删除当前工序下的对应设备
 */
const delEquipment = (row: ProcedureData, id: string) => {
    const { workingProcedureEquipments } = row;

    if (workingProcedureEquipments.length === 1) {
        row.workingProcedureEquipments = [regenEquipMent()]; // 当前工序下只有一个设备时进行数据重置初始化。
    } else {
        const rowIndex = workingProcedureEquipments.findIndex(item => item.markId === id);
        workingProcedureEquipments.splice(rowIndex, 1);
    }
};

/**
 * 清空工序所选的当前设备
 */
const clearEquipmentSelect = (row: WorkingProcedureEquipments) => {
    row.deviceName = null;
    row.equipmentId = null;
};

/**
 * 重新初始化生成辅助资源编码
 */
const regenAuiliary = (pMarkId: number) => {
    const markId = generateId();
    const auiliaryData = cloneDeep(initAuxiliary);
    auiliaryData.pMarkId = pMarkId;
    auiliaryData.markId = markId;
    return auiliaryData;
};

/**
 * 新增当前工序所在设备下的辅助资源编码
 */
const addAuxiliary = (row: ProcedureData, auxilary: WorkingProcedureAuxiliary) => {
    const auxiliaryData = row.workingProcedureEquipments.filter(
        item => item.markId === auxilary.pMarkId
    )[0];
    const data = regenAuiliary(auxilary.pMarkId as number);
    const rowIndex = auxiliaryData.workingProcedureAuxiliary.findIndex(
        item => item.markId === auxilary.markId
    );
    auxiliaryData.workingProcedureAuxiliary.splice(rowIndex + 1, 0, data);
};

/**
 * 删除当前工序所在设备下的辅助资源编码
 */
const delAuxiliary = (row: ProcedureData, auxilary: WorkingProcedureAuxiliary) => {
    const auxiliaryData = row.workingProcedureEquipments.filter(
        item => item.markId === auxilary.pMarkId
    )[0];
    const { workingProcedureAuxiliary } = auxiliaryData;

    if (workingProcedureAuxiliary.length === 1) {
        auxiliaryData.workingProcedureAuxiliary = [regenAuiliary(auxilary.pMarkId as number)]; // 当前工序中所处的设备下只存在一个辅助资源时进行数据重置初始化。
    } else {
        const rowIndex = workingProcedureAuxiliary.findIndex(
            item => item.markId === auxilary.markId
        );
        workingProcedureAuxiliary.splice(rowIndex, 1);
    }
};

/**
 * 清空工序所选设备中下对应的当前辅助编码
 */
const clearAuxiliarySelect = (row: WorkingProcedureAuxiliary) => {
    row.auxiliaryResourceName = null;
    row.auxiliaryId = null;
};

/**
 * 获取当前工序下所有设备辅助资源 & 获取当前工序下所有辅助资源名称
 */
const getAllAuxiliary = (data: WorkingProcedureEquipments[]) => {
    return data.map(equipment => equipment.workingProcedureAuxiliary).flat();
};

/**
 * 新增当前工序所属设备的辅助资源时，动获取动态设备编码&设备名称内边距
 * @tip {50.67} 表示一个单元格高度
 * @tip {8} 表示默认单元格下内边距的值
 */
const getDynamicPBottom = (auxilary: WorkingProcedureAuxiliary[]) => {
    const len = auxilary.length - 1;
    const bNum = 8;
    const pBottom = !len ? bNum : bNum + 50.67 * len;

    return pBottom + 'px';
};
</script>
<template>
    <q-page>
        <base-table
            ref="modalSlotRef"
            :table-config="tableConfig"
            add-table-row
            open-sticky
            :table-attr="{ showOverflowTooltip: false }"
            class="h-border m-procedure--add"
            @add="handleAdd"
        >
            <!-- 保存/取消 -->
            <template #tableHeadEnd>
                <q-submit-button
                    size="default"
                    :hide-label="true"
                    align="right"
                    :horizontal="true"
                    :loading="loading"
                    :cancel-button="false"
                    @save="handleOk"
                />
            </template>

            <!--  设备编码  -->
            <template #workingProcedureEquipments="{ row }">
                <q-form-item
                    v-for="item in row.workingProcedureEquipments"
                    id="1"
                    :key="item.equipmentId"
                    class="m-equipment__code"
                    :style="{
                        'padding-bottom': getDynamicPBottom(item.workingProcedureAuxiliary)
                    }"
                >
                    <q-virtual-select
                        v-model="item.equipmentNumber"
                        placeholder="请选择"
                        icon-class="xiala"
                        size="14px"
                        @click="openEquipment(row, item)"
                        @clear="clearEquipmentSelect(item)"
                    />

                    <q-icon
                        icon-class="a-zuhe560"
                        class="m-l-8 hover-icon"
                        size="21"
                        @click="addEquipment(row, item.markId)"
                    />
                    <q-icon
                        icon-class="a-zuhe557"
                        class="m-l-8 hover-icon"
                        size="20"
                        @click="delEquipment(row, item.markId)"
                    />
                </q-form-item>
            </template>

            <!-- 设备名称 -->
            <template #workingProcedureEquipmentsName="{ row }">
                <p
                    v-for="(item, index) in row.workingProcedureEquipments"
                    :key="index"
                    class="u-text"
                    :style="{
                        'padding-bottom': getDynamicPBottom(item.workingProcedureAuxiliary)
                    }"
                >
                    {{ transformValue(item.deviceName) }}
                </p>
            </template>

            <!--  辅助资源编码  -->
            <template #workingProcedureAuxiliary="{ row }">
                <q-form-item
                    v-for="item in getAllAuxiliary(row.workingProcedureEquipments)"
                    id="2"
                    :key="item.auxiliaryId!"
                    class="m-equipment__code"
                >
                    <q-virtual-select
                        v-model="item.auxiliaryDataCoding"
                        placeholder="请选择"
                        icon-class="xiala"
                        size="14px"
                        @click="openAuxiliary(row, item)"
                        @clear="clearAuxiliarySelect(item)"
                    />
                    <q-icon
                        icon-class="a-zuhe560"
                        class="m-l-8 hover-icon"
                        size="21"
                        @click="addAuxiliary(row, item)"
                    />
                    <q-icon
                        icon-class="a-zuhe557"
                        class="m-l-8 hover-icon"
                        size="20"
                        @click="delAuxiliary(row, item)"
                    />
                </q-form-item>
            </template>

            <!-- 辅助资源名称 -->
            <template #workingProcedureAuxiliaryName="{ row }">
                <p
                    v-for="(item, index) in getAllAuxiliary(row.workingProcedureEquipments)"
                    :key="index"
                    class="u-text"
                >
                    {{ transformValue(item.auxiliaryResourceName) }}
                </p>
            </template>
        </base-table>

        <!-- 加工设备 -->
        <equipment ref="equipmentRef" @submit="equipmentSubmit" />

        <!-- 辅助资源 -->
        <auxiliary ref="auxiliaryRef" @submit="auxiliarySubmit" />
    </q-page>
</template>

<style lang="scss" scoped>
@include b(m-equipment) {
    @include e(code) {
        @include flex();
    }
}

:deep() {
    @include b(m-procedure) {
        @include m(add) {
            .el-table .el-table__cell {
                vertical-align: top;

                div {
                    line-height: 32px;
                }
            }

            .el-table__body-wrapper .el-table-column--selection .el-checkbox,
            .el-table__header-wrapper .el-table-column--selection .el-checkbox {
                position: relative;
                top: 4px;
            }

            td.custom-cell {
                padding: 0;

                .cell {
                    padding: 0;
                }

                .q-form-item__content,
                .u-text {
                    &:last-child {
                        border-bottom: none;
                    }

                    padding: 8px 12px;
                    line-height: 34px;
                    border-bottom: var(--el-table-border);
                }
            }
        }
    }
}
</style>
